package com.gisquest.cloud.common.utils;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @Author guowei
 * @Date 2020/6/17 10:17
 * @Description:日期格式的转换及处理
 **/
public class DateUtil {

  public static final DateTimeFormatter COMPLICATED_FORMATTER_STR = DateTimeFormatter.ofPattern("yyyyMMddhhmmssSSS");
  public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  public static final String NORMAL_FORMAT = "yyyy-MM-dd HH:mm:ss";
  public static final String SIMPLE_FORMAT = "yyyy-MM-dd";
  public static final String SPECIAL_SIMPLE_FORMAT = "yyyy/MM/dd HH:mm:ss";
  private static AtomicBoolean isUse = new AtomicBoolean(false);
  private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat();

  public static String concurrentDateString() {
    return concurrentDateString("yyyy-MM-dd", new Date());
  }


  public static String concurrentDateString(String pattern, Date date) {
    while (!isUse.compareAndSet(false, true)) ;
    simpleDateFormat.applyPattern(pattern);
    String s = simpleDateFormat.format(date);
    isUse.compareAndSet(true, false);

    return s;
  }


  public static String getComplicatedStringFromDate(Date date) {
    LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    return localDateTime.format(COMPLICATED_FORMATTER_STR);
  }


  public static String getComplicatedStringFromDate() {
    LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
    return localDateTime.format(COMPLICATED_FORMATTER_STR);
  }


  public static Date getDateFromMilliStr(String milli) {
    return new Date(Long.valueOf(milli).longValue());
  }


  public static Date getDateFromStr(String dateStr) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
    LocalDateTime localDateTime = LocalDateTime.parse(dateStr, formatter);
    return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
  }


  public static long getDateGap(Date date) {
    long s1 = date.getTime();
    long s2 = System.currentTimeMillis();

    return (s2 - s1) / 86400000L;
  }


  public static String getDateString() {
    String currentDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
    return currentDate.replace("-", "");
  }


  public static String getDateString(String format) {
    if (("".equals(format)) || (format == null)) {
      format = "yyyy-MM-dd HH:mm:ss";
    }
    return new SimpleDateFormat(format).format(new Date());
  }


  public static Date getNextDayDate() {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(new Date());
    calendar.add(1, 6);
    return calendar.getTime();
  }


  public static Date getNextDayDate(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.add(1, 6);
    return calendar.getTime();
  }


  public static Date getNextHourTime(Date date) {
    LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    localDateTime = localDateTime.plus(1L, ChronoUnit.HOURS);
    return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
  }


  public static Date getNextMinutesTime(Date date, Long minutes) {
    LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    localDateTime = localDateTime.plus(minutes.longValue(), ChronoUnit.MINUTES);
    return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
  }


  public static Long getNumberOfMillisDifference(Date before, Date after) {
    Duration duration = getDifference(before, after);
    return Long.valueOf(duration.toMillis());
  }


  public static Duration getDifference(Date before, Date after) {
    return Duration.between(LocalDateTime.ofInstant(before.toInstant(), ZoneId.systemDefault()), LocalDateTime.ofInstant(after.toInstant(), ZoneId.systemDefault()));
  }


  public static Date getPreviousMinutesTime(Date date, Long minutes) {
    LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    localDateTime = localDateTime.plus(-minutes.longValue(), ChronoUnit.MINUTES);
    return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
  }


  public static Date getPreviousTime(int day) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(new Date());
    calendar.set(6, calendar.get(6) - day);
    return calendar.getTime();
  }


  public static String getStringFromDate(String format) {
    LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format, Locale.CHINA);
    return localDateTime.format(formatter);
  }


  public static String getStringFromDate(Date date) {
    LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    return localDateTime.format(DATE_TIME_FORMATTER);
  }


  public static String getStringFromDate() {
    LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
    return localDateTime.format(DATE_TIME_FORMATTER);
  }


  public static Integer getYear(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    return Integer.valueOf(calendar.get(1));
  }


  public static void main(String[] args) {
    Date date = new Date();
    long time = date.getTime();
    String str = getDateTime(time);
    System.out.println(str);
  }


  public static String getDateTime(long millseconds) {
    return new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date(millseconds));
  }


}
